home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 12 / QRZ Ham Radio Callsign Database - Volume 12.iso / windocs / qrztech.txt < prev    next >
Text File  |  1998-11-11  |  14KB  |  310 lines

  1.  
  2. The QRZ! Ham Radio CDROM 
  3. Callsign Database Technical Specification         Rev C October 1996
  4.  
  5.  
  6. The following information is provided for developers who wish to write
  7. their own software to directly access the QRZ callsign database files.
  8. Windows programmers including Visual C++ and Visual Basic users should
  9. refer to the help file called QRZDLL.HLP which documents database
  10. access through our custom dynamic link libraries, QRZDLL.DLL (for win3)
  11. and QRZ32.DLL (for Win95/NT).
  12.  
  13. Users of the QRZ! Ham Radio CDROM who wish to write their own callsign
  14. database search and retrieval software are encouraged to do so.  We
  15. welcome user contributed shareware programs for future versions of the
  16. QRZ! Ham Radio CDROM.
  17.  
  18.  
  19. Overview
  20.  
  21. There are three versions of the QRZ software for the PC, all of
  22. which share a common architecture.  Separate versions are provided
  23. for DOS, Windows 3.1 and Windows 95 and/or Windows NT.  All of the
  24. programs access the database using the same method.
  25.  
  26. The QRZ callsign database indexing and retrieval method was designed
  27. and optimized for CDROM use.  The primary goal was to provide fast
  28. searches for the most commonly sought after information.  A key to this
  29. strategy is the caching of index information in memory to minimize
  30. reads and more importantly, seeks from the CDROM drive.  The method
  31. described below implements one such strategy and has been shown to
  32. require only one CDROM head seek per database lookup.
  33.  
  34.  
  35. Database Structure
  36.  
  37. The QRZ callsign database is composed of four separate copies of the
  38. data, and four indices, each of which is sorted by different criteria.
  39. One copy is sorted by callsign, one by last name, one by city/state and
  40. one by zip code.  Due to differences in the way foreign addresses are
  41. represented, many DX countries are not represented in the City/State
  42. and Zip code databases.  These countries are generally searchable by
  43. callsign and/or name only.
  44.  
  45.  
  46. Data file    Index file    Database type
  47. -----------------------------------------------------
  48. callbkc.dat    callbkc.idx    Callsign
  49. callbkn.dat    callbkn.idx    Name
  50. callbks.dat    callbks.idx    State and City
  51. callbkz.dat    callbkz.idx    Zip Code
  52.  
  53.  
  54. All of the database files are located in the directory \CALLBK on the
  55. CDROM.  Each of the four datafiles (*.dat) is accompanied by a
  56. corresponding index file (*.idx).  The index files contain selected
  57. keys from their corresponding databases which were selected by sampling
  58. the databases at regular file offset intervals.  The sampling intervals
  59. are chosen to produce indices that are no more than 64 Kbytes in length
  60. so that they can each be contained within 64 Kb memory segments under
  61. DOS and Window 3.x.  The same indices are used in the Win32 environment
  62. despite the fact that there are no 64 Kbyte segment constraints, to
  63. preserve compatibility with Win3 and DOS programs.
  64.  
  65. The sampling interval for the index keys is subject to change from
  66. one release of the QRZ CDROM to the next and is therefore recorded
  67. as one of the critical operating parameters in the header of each
  68. index file.  This value, referred to as BytesPerKey, must be treated
  69. by your program as dynamic and must be fetched from each of the
  70. index headers at the start of each session.  A different BytesPerKey
  71. values is used for each database.
  72.  
  73. The index header occupies the first 48 bytes of the *.idx file and
  74. has the following format:
  75.  
  76. /*
  77. **     Index Header Block Definition (Version 2)
  78. **     (applies to all QRZ CDROMS from Version 2 onward) 
  79. **
  80. **     This block is located at the start of each index file
  81. */
  82. typedef struct {
  83.   char  DataName[16];    /* Name of the data file            */
  84.   char  BytesPerKey[8];  /* Data Bytes per Index Item        */
  85.   char  NumKeys[8];      /* Number of items in this index    */
  86.   char  KeyLen[8];       /* Length of each key item in bytes */
  87.   char  Version[8];      /* Database Version ID              */
  88. } index_header;
  89.  
  90. All values in the index header block are stored in ASCII character 
  91. representation.  These characters must be converted (by your program)
  92. into string or integer values as necessary.  Characters are left
  93. justified within each field and unused field characters (if any)
  94. are zero filled.  Your program should not depend on the presence of
  95. the null characters when reading these fields since some values could
  96. legitimately fill the entire field.
  97.  
  98.  
  99. Index Data Formats
  100.  
  101. Some number of keys (noted by the NumKeys field) immediately follow the
  102. index header block in the index file.  All fields in a given index
  103. file will have a width (in bytes) of 'KeyLen'.
  104.  
  105. The name index (CALLBKN.IDX) uses uniform keys which are set to a
  106. maximum of 'KeyLen' characters per name.  Longer names are simply
  107. truncated.  Names are stored in last-first format with a space between
  108. the two parts.  The city/state index (CALLBKC) also uses 'KeyLen'
  109. characters per entry with the two character state code occupying the
  110. first two characters and the city name in the last 10 characters.  For
  111. example, the town of Fremont, CA is represented as CAFREMONT in the
  112. index.  Callsigns (in CALLBKC.IDX) each occupy a different 'KeyLen'
  113. width slot (typically 6 characters wide) and zip code indices
  114. (CALLBKZ.IDX) do the same using a typical KeyLen value of 5.  Your
  115. program must always interpret KeyLen, BytesPerKey, and NumKeys and
  116. never make assumptions regarding their sizes.  These sizes could change
  117. in a future edition of the database and your program must be prepared
  118. to deal with it.
  119.  
  120.  
  121. Using the Index Header Block
  122.  
  123. The header block describes the field data which immediately follows
  124. it.  The records are tightly packed on 'BytesPerKey' boundaries without
  125. separators making them ideal candidates for use as memory arrays.
  126. Although unused key fields will be zero filled to the right, there is
  127. no guarantee that any given field will be null terminated.  Because of
  128. this, the indices must always be searched in a random access, fixed
  129. record length format.
  130.  
  131. A typical program will first search for the system drive that contains
  132. the \CALLBK base directory.  Next, the program will open and load each
  133. of the four indices into four separate 64 Kb memory buffers.  Searching
  134. the indices is then performed by addressing the buffers as one-dimensional
  135. arrays which contain 'NumKeys' elements that are each 'KeyLen' bytes wide.
  136.  
  137. A search for a particular item starts with the user inputting a desired
  138. key which is then formatted into an index key value.  The program then
  139. uses this key value to locate the closest match in the index table
  140. which is less than or equal to the the user supplied key.  For most
  141. machines a simple linear search of the table will be fast enough
  142. however a binary search algorithm can be employed.
  143.  
  144. After the relevant table key is chosen, it's ordinal position from the
  145. start of the table is saved in a variable called KeyOffset.  Next, the
  146. program must multiply the KeyOffset value by the BytesPerKey value
  147. which yields a DataOffset value.  This DataOffset value is then used as
  148. an index into the actual datafile (*.dat).
  149.  
  150. Typically, a program will use the DataOffset value as an argument to a
  151. File Seek system call ( fseek() ).  Once the file pointer is positioned
  152. at the DataOffset, the program can then begin a linear search for the
  153. desired record in the database.  Again, a binary search between the
  154. [DataOffset] and [KeyOffset+1*BytesPerKey] can be used however experience
  155. has shown this will provide only a minimal improvement in performance.
  156.  
  157. Be aware that the derived DataOffset value will usually land you in the
  158. middle of some record.  This is typical and you will find that the
  159. callsign that was pointed to by the index key will be located at the
  160. beginning of the next text line in the file.  The data file is an
  161. ordinary ASCII text file with a single newline (0x0a) character at
  162. the end of each line.
  163.  
  164. The search of the data file should terminate at offset
  165. [KeyOffset+1 * BytesPerKey] if the desired record has not yet been found.
  166.  
  167.  
  168. Database Format
  169.  
  170. The database files all have the same format.  They are ASCII files
  171. which consist of one text line per record.  Each record consists of a
  172. fixed number of comma separated fields with blank fields represented by
  173. consecutive commas.  Each line is terminated with a single ASCII
  174. newline ('\n', 0x0a, or chr$(10)) character.
  175.  
  176. Every record has the same number of commas in it, except for
  177. cross-reference records, which are discussed below.  If the data itself
  178. is supposed to contain a comma, then it is represented in the database
  179. by a semi-colon ';' which should be replaced by a comma in the program's
  180. text output formatting routine.
  181.  
  182.  
  183. Here's an example of one record from the database:
  184.  
  185. AA7BQ ,LLOYD,,FRED L,,53340,90009,00009,8215 E WOOD DR,SCOTTSDALE,AZ,
  186. 85260,E,KJ6RK,A
  187.  
  188. /*
  189. **    Standard Record Field Offsets
  190. */
  191. #define Callsign        0       AA7BQ
  192. #define LastName        1       LLOYD
  193. #define JR              2       (reserved) *
  194. #define FirstName       3       FRED L
  195. #define MI              4       (reserved) *
  196. #define DateOfBirth     5       53340        // Dec 6, 1953
  197. #define EffectiveDate   6       90009        // Jan 9, 1990
  198. #define ExpirationDate  7       00009        // Jan 9, 2000
  199. #define MailStreet      8       8215 E. Wood DR
  200. #define MailCity        9       SCOTTSDALE
  201. #define MailState       10      AZ
  202. #define ZipCode         11      85260 
  203. #define LicenseClass    12      E        // (P = TechPlus)
  204. #define PreviousCall    13      KJ6RK 
  205. #define PreviousClass   14      A 
  206.  
  207.  
  208. * The fields JR and MI were obsoleted by the FCC in July 1994.
  209. QRZ uses these fields by inserting a period (.) into them to indicate
  210. the presense of additional information elsewhere on the CDROM.  In
  211. particular, QRZ inserts a period into the JR field when the indicated
  212. callsign has an email address registered in the email database.  A
  213. period in the MI field is used to indicate that the CDROM contains a
  214. GIF image file for the indicated callsign.  Gif files are found in
  215. \CALLBK\GIFS and are named <callsign>.gif.
  216.  
  217. Note: The email database is proprietary and is not documented or
  218. accessible to user-developed programs.  Access routines are provided
  219. to C++ and Visual Basic users through the QRZ DLL's.
  220.  
  221.  
  222. Callsign Collating Sequence
  223.  
  224. Callsigns in the QRZ databases are stored in a special columnar format
  225. which aids in performing searches.  With this format, the area digit
  226. part of the callsign is always in the same position.  Callsigns are
  227. considered to have a prefix, an area number and a suffix.  Collating
  228. preference is always given in reverse order, that is, suffix followed
  229. by area number followed by prefix.  When callsigns are compared for
  230. sorting and searching, a this collating sequence (called 'defcab') is
  231. applied to the callsign which results in the following logical behavior:
  232.  
  233.  
  234.          abcdef  sort order  reason
  235.     -------- ---------- ---------
  236.     "KB3A  "    1st       def
  237.         "KB2AB "    2nd       defc
  238.     "K 5AB "    3rd       def
  239.         "KB1ABC"    4th       defc
  240.     "K 4ABC"    5th       defca
  241.     "WA4ABC"    6th       defcab
  242.     "WB4ABC"    7th 
  243.  
  244.  
  245. The 'reason' lists why each entry deserves its position in the list
  246. above the one below it.
  247.  
  248. To compare two callsigns for greater than, less than or equality, the
  249. program must first transpose them into 'defcab' format (using spaces
  250. for unused positions) and then do a left-to-right comparison of the two.
  251. For example, to compare K1ABC against KC8AB, the program would do the
  252. following:
  253.                                   defcab
  254. callsign K1ABC is transposed to: "ABC1K "
  255. callsign KB8AB is transposed to: "AB 8KC"
  256.  
  257. then, a string compare as in:    strcmp("ABC1K ", "AB 8KB")
  258.  
  259. will return a "greater than" value meaning that K1ABC comes _after_
  260. KB8AB in the database having been found greater at point 'f' in the
  261. defcab sequence.
  262.  
  263.  
  264. Date Formats
  265.  
  266. All dates are stored in 5 character Julian format, e.g. 93003 equals
  267. January 3, 1993 or the 3rd day of 1993.  Dates before 1900 or after
  268. year 2000 must be determined by the context in which they are used.
  269. In other words, if the resultant age does not make sense, then it is
  270. wrong.  For example, all licenses expire in the future so for license
  271. expiration dates 02 must mean 2002.  Birthdays are more difficult to
  272. judge but most can be arbitrarily considered to be greater than 10
  273. years old.  This is not a perfect method, but it does yield
  274. satisfactory overall results.
  275.  
  276.  
  277. Cross Reference Information
  278.  
  279. When the FCC supplies a "previous callsign" in their database, it
  280. is used by QRZ to construct a cross reference so that a person can
  281. be found by their old call as well as their new one.
  282.  
  283. A cross reference record is distinguished from other records as one
  284. which contains only one comma.  A cross-reference record takes the
  285. form of "OldCall,NewCall" with no other information on the line.
  286.  
  287. When a cross reference record is encountered, your program must fetch
  288. the second field and restart the search from the beginning to return
  289. the primary reference.
  290.  
  291.  
  292. Summary
  293.  
  294. It is the desire of QRZ to maintain this database and index format on
  295. all future releases of the QRZ CDROM.  It would be nice to find a
  296. method for extending the data to include Vanity callsign status while
  297. preserving compatibility with older programs. We are currently considering
  298. appending a dot (.) to the license class (e.g. "E.") if the callsign was
  299. issued under the Vanity program.  Your comments are welcome on this idea.
  300.  
  301. Please address programming questions and/or comments to:
  302.  
  303. flloyd@qrz.com
  304.  
  305. -------------------------------------------------------------------
  306.  
  307. Fred Lloyd, AA7BQ   10/26/96
  308.  
  309.  
  310.